package com.come4loves.game.module.fight.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import com.alibaba.fastjson.JSON;
import com.come4loves.game.module.card.constant.CardType;
import com.come4loves.game.module.card.helper.CardHelper;
import com.come4loves.game.module.card.model.CardModel;
import com.come4loves.game.module.fight.constants.BuffType;
import com.come4loves.game.module.fight.constants.SkillMoment;
import com.come4loves.game.module.skill.model.SkillModel;

public class FightCard {
	/**
	 * 卡牌标识
	 */
	private int id;

	/**
	 * 卡牌配置id
	 */
	private int cfgId;
	/**
	 * 法力值
	 */
	private int magic;
	/**
	 * 攻击力
	 */
	private int attack;
	/**
	 * 血量
	 */
	private int hp;
	/**
	 * 血量最大值
	 */
	private int maxHp;
	/**
	 * 速度
	 */
	private int speed;

	/**
	 * 出牌初始值
	 */
	private int initValue = 3;

	/**
	 * 标记是什么类型的卡
	 * 
	 */
	private CardType cardType;

	/**
	 * 是否是召唤
	 */
	private boolean summon = false;

	/**
	 * buf列表
	 */
	private Map<BuffType, List<BuffData>> buffers = new HashMap<BuffType, List<BuffData>>();

	private Map<SkillMoment, List<SkillModel>> skills = new HashMap<SkillMoment, List<SkillModel>>();

	private Map<String, Integer> castTargets = new HashMap<String, Integer>();
	private Map<String, Integer> aiTargets = new HashMap<String, Integer>();

	public FightCard() {

	}

	public FightCard(int cfgId, int magic, int attack, int hp, int speed, int initValue) {
		super();
		this.cfgId = cfgId;
		this.magic = magic;
		this.attack = attack;
		this.hp = hp;
		this.maxHp = this.hp;
		this.speed = speed;
		this.initValue = initValue;
	}

	public void reset() {
		buffers.clear();
		CardHelper.getDataConfigByCardType(this, this.cardType, this.cfgId);
	}

	public static FightCard valueOf(CardType cardType, CardModel model) {
		FightCard fightCard = new FightCard();
		fightCard.cardType = cardType;
		fightCard = CardHelper.getDataConfigByCardType(fightCard, cardType, model.cfgId);
		return fightCard;
	}

	public static FightCard valueOf(CardType cardType, int cardId) {
		FightCard fightCard = new FightCard();
		fightCard.cardType = cardType;
		fightCard = CardHelper.getDataConfigByCardType(fightCard, cardType, cardId);
		return fightCard;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public int getCfgId() {
		return cfgId;
	}

	public void setCfgId(int cfgId) {
		this.cfgId = cfgId;
	}

	public int getMagic() {
		return magic;
	}

	public void setMagic(int magic) {
		this.magic = magic;
	}

	public int getAttack() {
		List<BuffData> list = getBuff(BuffType.ATKMODIFIER);
		int bvalue = 0;
		for (BuffData buffData : list) {
			bvalue += buffData.getBuffValue();
		}
		return attack + bvalue;
	}

	public void setAttack(int attack) {
		this.attack = attack;
	}

	public int getHp() {
		return hp;
	}

	public void setHp(int hp) {
		this.hp = hp;
	}

	public int getSpeed() {
		return speed;
	}

	public void setSpeed(int speed) {
		this.speed = speed;
	}

	public boolean isDead() {
		return this.hp <= 0;
	}

	public void addBuff(BuffData buffData) {
		List<BuffData> list = null;
		if (this.buffers.containsKey(buffData.getBuffType())) {
			list = this.buffers.get(buffData.getBuffType());
		} else {
			list = new ArrayList<BuffData>();
			this.buffers.put(buffData.getBuffType(), list);
		}
		list.add(buffData);
	}

	public CardType getCardType() {
		return cardType;
	}

	public int getInitValue() {
		return initValue;
	}

	public void setInitValue(int initValue) {
		this.initValue = initValue;
	}

	public List<BuffData> getBuff(BuffType type) {
		List<BuffData> result = new ArrayList<BuffData>();
		if (type == null) {
			return result;
		}
		if (this.buffers.containsKey(type)) {
			return this.buffers.get(type);
		}
		return result;
	}

	public List<BuffData> getBuffers() {
		List<BuffData> result = new ArrayList<BuffData>();
		for (List<BuffData> list : buffers.values()) {
			result.addAll(list);
		}
		return result;
	}

	public BuffData removeBuff(BuffData buffData) {
		Iterator<List<BuffData>> it = this.buffers.values().iterator();
		while (it.hasNext()) {
			List<BuffData> list = it.next();
			Iterator<BuffData> itt = list.iterator();
			while (itt.hasNext()) {
				BuffData bd = itt.next();
				if (bd == buffData) {
					itt.remove();
					return bd;
				}
			}
		}
		return null;
	}

	public BuffData removeBuff(int userId) {
		Iterator<List<BuffData>> it = this.buffers.values().iterator();
		while (it.hasNext()) {
			List<BuffData> list = it.next();
			Iterator<BuffData> itt = list.iterator();
			while (itt.hasNext()) {
				BuffData bd = itt.next();
				if (bd.getUseId() == userId) {
					itt.remove();
					return bd;
				}
			}
		}
		return null;
	}

	@Override
	public String toString() {
		return JSON.toJSONString(this);
	}

	public List<SkillModel> getSkill(SkillMoment moment) {
		return skills.get(moment);
	}

	public Map<String, Integer> getCastTargets() {
		return castTargets;
	}
	public Map<String, Integer> getAiTargets() {
		return aiTargets;
	}

	/**
	 * 是否可以行动
	 * 
	 * @return
	 */
	public boolean isAction() {
		if (isBuffAble(BuffType.SLEEP))
			return false;
		if (isBuffAble(BuffType.ICED))
			return false;
		if (isBuffAble(BuffType.STUNNED))
			return false;
		return true;
	}

	public void addSkill(SkillMoment moment, SkillModel model) {
		List<SkillModel> list = null;
		if (this.skills.containsKey(moment)) {
			list = this.skills.get(moment);
		} else {
			list = new ArrayList<SkillModel>();
			this.skills.put(moment, list);
		}
		list.add(model);
	}

	public int getMaxHp() {

		List<BuffData> list = getBuff(BuffType.HPMAXMODIFIER);
		int bvalue = 0;
		for (BuffData buffData : list) {
			bvalue += buffData.getBuffValue();
		}

		int result = this.maxHp;
		return result + bvalue;
	}

	public void setMaxHp(int maxHp) {
		this.maxHp = maxHp;
	}

	/**
	 * 查看buff是否有效
	 * 
	 * @param buffType
	 * @return
	 */
	public boolean isBuffAble(BuffType buffType) {
		for (List<BuffData> list : this.buffers.values()) {
			for (BuffData buffData : list) {
				if (buffData.getBuffType().equals(buffType) && !buffData.isTimeOut()) {
					return true;
				}
			}
		}
		return false;
	}

	public List<BuffData> removeBuff(BuffType buffType) {
		List<BuffData> list = getBuff(buffType);
		Iterator<BuffData> it = list.iterator();
		while (it.hasNext()) {
			it.remove();
		}
		return list;
	}

	public void setSummon(boolean summon) {
		this.summon = summon;
	}

	public boolean isSummon() {
		return summon;
	}

	public Map<SkillMoment, List<SkillModel>> getSkills() {
		return skills;
	}

	@Override
	public int hashCode() {
		return Objects.hash(id);
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		FightCard other = (FightCard) obj;
		if (id != other.id)
			return false;
		return true;
	}

	public boolean isGenenral() {
		return this.getCardType().equals(CardType.GENERAL);
	}

	public String simpleInfo() {
		return "{cardType:" + this.cardType.toString() + ",card cfgId: " + this.cfgId + "}";
	}

}
